package admin.iss.nus.edu.sg;

import java.util.List;

import sg.edu.nus.iss.CONFIG;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.dynamodb.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodb.model.CreateTableRequest;
import com.amazonaws.services.dynamodb.model.DeleteTableRequest;
import com.amazonaws.services.dynamodb.model.DescribeTableRequest;
import com.amazonaws.services.dynamodb.model.DescribeTableResult;
import com.amazonaws.services.dynamodb.model.KeySchema;
import com.amazonaws.services.dynamodb.model.KeySchemaElement;
import com.amazonaws.services.dynamodb.model.ListTablesResult;
import com.amazonaws.services.dynamodb.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodb.model.TableDescription;
import com.amazonaws.services.dynamodb.model.TableStatus;

public class DynamoDB {
	
	private static AmazonDynamoDBClient dynamoDB;
	
	
	static
	{
		try {
			init();
		} catch (Exception e) {
			System.out.println("Exception while creating initializing Dynamo Client...");
			e.printStackTrace();
			dynamoDB = null;
		}
	}
	public static void init() throws Exception {
    	System.out.println("init dynamo...");
    	AWSCredentials credentials = new BasicAWSCredentials(CONFIG.ACCESS_KEY,CONFIG.SECRET_KEY);
		System.out.println("key is:"+ credentials.getAWSSecretKey());
        dynamoDB = new AmazonDynamoDBClient(credentials);
        
        dynamoDB.setEndpoint(CONFIG.END_POINT);
        System.out.println("done");
     
    }
	
	public static AmazonDynamoDBClient client()
	{
		return dynamoDB;
	}
	public static void createTable(String name,String primaryKey,String primaryKeyType)
	{
		KeySchema schema = new KeySchema();
		schema.setHashKeyElement(new KeySchemaElement().withAttributeName(primaryKey).withAttributeType(primaryKeyType));
		 // Create a table with a primary key named 'name', which holds a string
        CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(name)
            .withKeySchema(schema)
            .withProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits(10L).withWriteCapacityUnits(10L));
        TableDescription createdTableDescription = dynamoDB.createTable(createTableRequest).getTableDescription();
        System.out.println("Created Table: " + createdTableDescription);
	}
	
	public static void createTable(String name,String primaryKey,String primaryKeyType,String rangeKey,String rangeKeyType)
	{
		 // Create a table with a primary key named 'name', which holds a string
		KeySchema schema = new KeySchema();
		schema.setHashKeyElement(new KeySchemaElement().withAttributeName(primaryKey).withAttributeType(primaryKeyType));
		schema.setRangeKeyElement(new KeySchemaElement().withAttributeName(rangeKey).withAttributeType(rangeKeyType));
		
        CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(name)
            .withKeySchema(schema)
            .withProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits(10L).withWriteCapacityUnits(10L));
        TableDescription createdTableDescription = dynamoDB.createTable(createTableRequest).getTableDescription();
        System.out.println("Created Table: " + createdTableDescription);
	}
	
	public static void deleteTable(String tableName)
	{
		dynamoDB.deleteTable(new DeleteTableRequest(tableName));
	}
	
	public static List<String> listTables()
	{
		ListTablesResult results = dynamoDB.listTables();
		return results.getTableNames();
		
	}
	
	public static void waitForTableToBecomeAvailable(String tableName) {
        System.out.println("Waiting for " + tableName + " to become ACTIVE...");

        long startTime = System.currentTimeMillis();
        long endTime = startTime + (10 * 60 * 1000);
        while (System.currentTimeMillis() < endTime) {
            try {Thread.sleep(1000 * 20);} catch (Exception e) {}
            try {
                DescribeTableRequest request = new DescribeTableRequest().withTableName(tableName);
                DescribeTableResult result = dynamoDB.describeTable(request);
                TableDescription tableDescription = result.getTable();
                String tableStatus = tableDescription.getTableStatus();
                System.out.println("  - current state: " + tableStatus);
                if (tableStatus.equals(TableStatus.ACTIVE.toString())) return;
            } catch (AmazonServiceException ase) {
                if (ase.getErrorCode().equalsIgnoreCase("ResourceNotFoundException") == false) throw ase;
            }
        }

        throw new RuntimeException("Table " + tableName + " never went active");
    }
}
